//
// MudTools.OfficeInterop 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证（版本 2.0）进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动！任何基于本项目二次开发而产生的一切法律纠纷和责任，我们不承担任何责任！

namespace MudTools.OfficeInterop.Word.Imps;

/// <summary>
/// 封装 Microsoft.Office.Interop.Word.Styles 的实现类。
/// </summary>
internal class WordStyles : IWordStyles
{
    private MsWord.Styles _styles;
    private bool _disposedValue;

    /// <summary>
    /// 构造函数，包装 COM 对象。
    /// </summary>
    /// <param name="styles">原始 COM Styles 对象。</param>
    internal WordStyles(MsWord.Styles styles)
    {
        _styles = styles ?? throw new ArgumentNullException(nameof(styles));
        _disposedValue = false;
    }

    #region 属性实现

    /// <inheritdoc/>
    public IWordApplication? Application => _styles != null ? new WordApplication(_styles.Application) : null;

    /// <inheritdoc/>
    public object Parent => _styles?.Parent;

    /// <inheritdoc/>
    public int Count => _styles?.Count ?? 0;

    /// <inheritdoc/>
    public IWordStyle this[int index]
    {
        get
        {
            if (_styles == null || index < 1 || index > Count)
                return null;

            try
            {
                var style = _styles[index];
                return new WordStyle(style);
            }
            catch
            {
                return null;
            }
        }
    }

    /// <inheritdoc/>
    public IWordStyle this[string name]
    {
        get
        {
            if (_styles == null || string.IsNullOrWhiteSpace(name))
                return null;

            try
            {
                var style = _styles[name];
                return style != null ? new WordStyle(style) : null;
            }
            catch
            {
                return null;
            }
        }
    }

    /// <inheritdoc/>
    public IWordStyle DefaultParagraphStyle =>
        this[MsWord.WdBuiltinStyle.wdStyleNormal.ToString()] ?? this["正文"];

    /// <inheritdoc/>
    public IWordStyle DefaultCharacterStyle =>
        this[MsWord.WdBuiltinStyle.wdStyleDefaultParagraphFont.ToString()];

    /// <inheritdoc/>
    public IWordStyle GetDefaultStyle(MsWord.WdStyleType styleType)
    {
        if (_styles == null)
            return null;

        try
        {
            switch (styleType)
            {
                case MsWord.WdStyleType.wdStyleTypeParagraph:
                    return DefaultParagraphStyle;
                case MsWord.WdStyleType.wdStyleTypeCharacter:
                    return DefaultCharacterStyle;
                default:
                    return null;
            }
        }
        catch
        {
            return null;
        }
    }

    #endregion

    #region 方法实现

    /// <inheritdoc/>
    public IWordStyle Add(string name, WdStyleType type = WdStyleType.wdStyleTypeParagraph)
    {
        if (_styles == null)
        {
            throw new ObjectDisposedException(nameof(WordStyles));
        }

        if (string.IsNullOrWhiteSpace(name))
            throw new ArgumentException("样式名称不能为空。", nameof(name));

        try
        {
            var newStyle = _styles.Add(name, (MsWord.WdStyleType)(int)type);
            return new WordStyle(newStyle);
        }
        catch (COMException ex)
        {
            throw new InvalidOperationException($"无法添加样式 '{name}'。", ex);
        }
    }

    /// <inheritdoc/>
    public bool Contains(string name)
    {
        if (_styles == null || string.IsNullOrWhiteSpace(name))
            return false;

        return _styles[name] != null;
    }

    /// <inheritdoc/>
    public List<string> GetStyleNamesByType(WdStyleType styleType)
    {
        var names = new List<string>();

        if (_styles == null)
            return names;

        for (int i = 1; i <= Count; i++)
        {
            var style = _styles[i];
            if (style != null && style.Type == (MsWord.WdStyleType)(int)styleType)
            {
                names.Add(style.NameLocal);
            }
        }

        return names;
    }

    /// <inheritdoc/>
    public List<string> GetAllStyleNames()
    {
        var names = new List<string>();

        if (_styles == null)
            return names;

        for (int i = 1; i <= Count; i++)
        {
            var style = _styles[i];
            if (style?.NameLocal != null)
            {
                names.Add(style.NameLocal);
            }
        }

        return names;
    }

    /// <inheritdoc/>
    public List<string> GetBuiltInStyleNames()
    {
        var names = new List<string>();

        if (_styles == null)
            return names;

        for (int i = 1; i <= Count; i++)
        {
            var style = _styles[i];
            if (style != null && style.BuiltIn)
            {
                names.Add(style.NameLocal);
            }
        }

        return names;
    }

    /// <inheritdoc/>
    public List<string> GetCustomStyleNames()
    {
        var names = new List<string>();

        if (_styles == null)
            return names;

        for (int i = 1; i <= Count; i++)
        {
            var style = _styles[i];
            if (style != null && style.BuiltIn)
            {
                names.Add(style.NameLocal);
            }
        }

        return names;
    }


    /// <inheritdoc/>
    public bool DeleteStyle(string name)
    {
        if (_styles == null || string.IsNullOrWhiteSpace(name))
            return false;

        var style = _styles[name];
        if (style != null && style.BuiltIn) // 只能删除自定义样式
        {
            style.Delete();
            return true;
        }
        return false;
    }

    /// <inheritdoc/>
    public void ClearCustomStyles()
    {
        if (_styles == null)
            return;

        var customStyles = GetCustomStyleNames();
        foreach (var styleName in customStyles)
        {
            DeleteStyle(styleName);
        }
    }

    #endregion

    #region IEnumerable<IWordStyle> 实现

    /// <inheritdoc/>
    public IEnumerator<IWordStyle> GetEnumerator()
    {
        if (_styles == null)
            yield break;

        for (int i = 1; i <= Count; i++)
        {
            var style = _styles[i];
            if (style != null)
                yield return new WordStyle(style);
        }
    }

    /// <inheritdoc/>
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    #endregion

    #region IDisposable 实现

    /// <summary>
    /// 释放 COM 对象资源。
    /// </summary>
    /// <param name="disposing">是否由用户主动调用 Dispose。</param>
    protected virtual void Dispose(bool disposing)
    {
        if (_disposedValue) return;

        if (disposing && _styles != null)
        {
            System.Runtime.InteropServices.Marshal.ReleaseComObject(_styles);
            _styles = null;
        }

        _disposedValue = true;
    }

    /// <inheritdoc/>
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    #endregion
}